#include "selfinfowidget.h"

#include <QCursor>
#include <QGridLayout>
#include <QTimer>
#include <QFileDialog>

#include "model/datacenter.h"
#include "debug.h"
#include "toast.h"

using namespace model;

SelfInfoWidget::SelfInfoWidget(QWidget *parent) : QDialog(parent) {
    // 1. 设置整个窗口的属性
    this->setFixedSize(500, 250);
    this->setWindowTitle("个人信息");
    this->setWindowIcon(QIcon(":/resource/image/logo.png"));
    // 窗口被关闭时，自动销毁这个对话框对象
    this->setAttribute(Qt::WA_DeleteOnClose);
    // 把窗口移动到鼠标当前的位置
    this->move(QCursor::pos());

    // 2. 创建布局管理器
    layout = new QGridLayout();
    // layout->setSpacing(0);
    layout->setHorizontalSpacing(10);
    layout->setVerticalSpacing(3);
    layout->setContentsMargins(10, 10, 10, 0);
    layout->setAlignment(Qt::AlignTop);
    this->setLayout(layout);

    // 3. 创建头像
    avatarBtn = new QPushButton();
    avatarBtn->setFixedSize(75, 75);
    avatarBtn->setIconSize(QSize(75, 75));
    avatarBtn->setStyleSheet("QPushButton { border: none; background-color: transparent; }");
    layout->addWidget(avatarBtn, 0, 0, 3, 1);

    QString labelStyle = "QLabel { font-size: 14px; font-weight: 800; }";
    QString btnStyle = "QPushButton { border: none; background-color: transparent; }";
    btnStyle += "QPushButton:pressed { background-color: rgb(210, 210, 210); }";
    QString editStyle = "QLineEdit { border: none; border-radius: 5px; padding-left: 2px; }";

    int height = 30;

    // 4. 添加用户的 id 信息
    idTag = new QLabel();
    idTag->setFixedSize(50, height);
    idTag->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    idTag->setText("序号");
    idTag->setStyleSheet(labelStyle);

    idLabel = new QLabel();
    idLabel->setFixedHeight(height);
    idLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

    // 5. 添加用户名字的显示
    nameTag = new QLabel();
    nameTag->setFixedSize(50, height);
    nameTag->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    nameTag->setText("昵称");
    nameTag->setStyleSheet(labelStyle);

    nameLabel = new QLabel();
    nameLabel->setFixedHeight(height);
    nameLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

    nameModifyBtn = new QPushButton();
    nameModifyBtn->setFixedSize(70, 25);
    nameModifyBtn->setIconSize(QSize(20, 20));
    nameModifyBtn->setIcon(QIcon(":/resource/image/modify.png"));
    nameModifyBtn->setStyleSheet(btnStyle);

    nameEdit = new QLineEdit();
    nameEdit->setFixedHeight(height);
    nameEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    nameEdit->setStyleSheet(editStyle);
    nameEdit->hide();

    nameSubmitBtn = new QPushButton();
    nameSubmitBtn->setFixedSize(70, 25);
    nameSubmitBtn->setIconSize(QSize(20, 20));
    nameSubmitBtn->setIcon(QIcon(":/resource/image/submit.png"));
    nameSubmitBtn->setStyleSheet(btnStyle);
    nameSubmitBtn->hide();

    // 6. 添加个性签名
    signTag = new QLabel();
    signTag->setFixedSize(50, height);
    signTag->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    signTag->setText("签名");
    signTag->setStyleSheet(labelStyle);

    signLabel = new QLabel();
    signLabel->setFixedHeight(height);
    signLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

    signModifyBtn = new QPushButton();
    signModifyBtn->setFixedSize(70, 25);
    signModifyBtn->setIconSize(QSize(20, 20));
    signModifyBtn->setIcon(QIcon(":/resource/image/modify.png"));
    signModifyBtn->setStyleSheet(btnStyle);

    signEdit = new QLineEdit();
    signEdit->setFixedHeight(height);
    signEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    signEdit->setStyleSheet(editStyle);
    signEdit->hide();

    signSubmitBtn = new QPushButton();
    signSubmitBtn->setFixedSize(70, 25);
    signSubmitBtn->setIconSize(QSize(20, 20));
    signSubmitBtn->setIcon(QIcon(":/resource/image/submit.png"));
    signSubmitBtn->setStyleSheet(btnStyle);
    signSubmitBtn->hide();

    // 7. 添加电话
    phoneTag = new QLabel();
    phoneTag->setFixedSize(50, height);
    phoneTag->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    phoneTag->setText("电话");
    phoneTag->setStyleSheet(labelStyle);

    phoneLabel = new QLabel();
    phoneLabel->setFixedHeight(height);
    phoneLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

    phoneModifyBtn = new QPushButton();
    phoneModifyBtn->setFixedSize(70, 25);
    phoneModifyBtn->setIconSize(QSize(20, 20));
    phoneModifyBtn->setIcon(QIcon(":/resource/image/modify.png"));
    phoneModifyBtn->setStyleSheet(btnStyle);

    phoneEdit = new QLineEdit();
    phoneEdit->setFixedHeight(height);
    phoneEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    phoneEdit->setStyleSheet(editStyle);
    phoneEdit->hide();

    phoneSubmitBtn = new QPushButton();
    phoneSubmitBtn->setFixedSize(70, 25);
    phoneSubmitBtn->setIconSize(QSize(20, 20));
    phoneSubmitBtn->setIcon(QIcon(":/resource/image/submit.png"));
    phoneSubmitBtn->setStyleSheet(btnStyle);
    phoneSubmitBtn->hide();

    // 8. 添加验证码
    verifyCodeTag = new QLabel();
    verifyCodeTag->setFixedSize(50, height);
    verifyCodeTag->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    verifyCodeTag->setText("验证码");
    verifyCodeTag->setStyleSheet(labelStyle);
    verifyCodeTag->hide();

    verifyCodeEdit = new QLineEdit();
    verifyCodeEdit->setFixedHeight(height);
    verifyCodeEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    verifyCodeEdit->setStyleSheet(editStyle);
    verifyCodeEdit->hide();

    getVerifyCodeBtn = new QPushButton();
    getVerifyCodeBtn->setText("获取验证码");
    getVerifyCodeBtn->setStyleSheet(btnStyle);
    getVerifyCodeBtn->setFixedSize(70, height);
    getVerifyCodeBtn->hide();

    // 9. 添加到布局管理器 第0列被头像占用了，下列都是从第一列开始的
    layout->addWidget(idTag, 0, 1);
    layout->addWidget(idLabel, 0, 2);

    layout->addWidget(nameTag, 1, 1);
    layout->addWidget(nameLabel, 1, 2);
    layout->addWidget(nameModifyBtn, 1, 3);

    layout->addWidget(signTag, 2, 1);
    layout->addWidget(signLabel, 2, 2);
    layout->addWidget(signModifyBtn, 2, 3);

    layout->addWidget(phoneTag, 3, 1);
    layout->addWidget(phoneLabel, 3, 2);
    layout->addWidget(phoneModifyBtn, 3, 3);

#if TEST_UI
    idLabel->setText("1234");
    nameLabel->setText("张三");
    signLabel->setText("从今天开始认真敲代码");
    phoneLabel->setText("18912345678");
    avatarBtn->setIcon(QIcon(":/resource/image/defaultAvatar.png"));
#endif

    // 10. 连接信号槽
    initSignalSlot();

    // 11. 加载数据到界面上
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    UserInfo* myself = dataCenter->getMyself();
    if (myself != nullptr) {
        avatarBtn->setIcon(myself->avatar);
        idLabel->setText(myself->userId);
        nameLabel->setText(myself->nickname);
        signLabel->setText(myself->signature);
        phoneLabel->setText(myself->phone);
    }
}

void SelfInfoWidget::initSignalSlot()
{
    connect(nameModifyBtn, &QPushButton::clicked, this, [=]() {
        // 把当前的 nameLabel 和 nameModifyBtn 隐藏起来
        nameLabel->hide();
        nameModifyBtn->hide();
        layout->removeWidget(nameLabel);
        layout->removeWidget(nameModifyBtn);
        // 把 nameEdit 和 nameSubmitBtn 显示出来
        nameEdit->show();
        nameSubmitBtn->show();
        layout->addWidget(nameEdit, 1, 2);
        layout->addWidget(nameSubmitBtn, 1, 3);
        // 把输入框的内容进行设置
        nameEdit->setText(nameLabel->text());
    });

    connect(signModifyBtn, &QPushButton::clicked, this, [=]() {
        // 把当前的 signLabel 和 signModifyBtn 隐藏起来
        signLabel->hide();
        signModifyBtn->hide();
        layout->removeWidget(signLabel);
        layout->removeWidget(signModifyBtn);
        // 把 signEdit 和 signSubmitBtn 显示出来
        signEdit->show();
        signSubmitBtn->show();
        layout->addWidget(signEdit, 2, 2);
        layout->addWidget(signSubmitBtn, 2, 3);
        // 把输入框的内容进行设置
        signEdit->setText(signLabel->text());
    });

    connect(phoneModifyBtn, &QPushButton::clicked, this, [=]() {
        if (this->leftTime != 30) {
            Toast::showMessage("修改过于频繁，请稍后重试");
            return ;
        }
        // 把当前的 phoneLabel 和 phoneModifyBtn 隐藏起来
        phoneLabel->hide();
        phoneModifyBtn->hide();
        layout->removeWidget(phoneLabel);
        layout->removeWidget(phoneModifyBtn);
        // 把 phoneEdit 和 phoneSubmitBtn 显示出来
        phoneEdit->show();
        phoneSubmitBtn->show();
        layout->addWidget(phoneEdit, 3, 2);
        layout->addWidget(phoneSubmitBtn, 3, 3);

        verifyCodeTag->show();
        verifyCodeEdit->show();
        getVerifyCodeBtn->show();
        layout->addWidget(verifyCodeTag, 4, 1);
        layout->addWidget(verifyCodeEdit, 4, 2);
        layout->addWidget(getVerifyCodeBtn, 4, 3);

        // 把输入框的内容进行设置
        phoneEdit->setText(phoneLabel->text());
    });

    connect(nameSubmitBtn, &QPushButton::clicked, this, &SelfInfoWidget::clieckNameSubmitBtn);
    connect(signSubmitBtn, &QPushButton::clicked, this, &SelfInfoWidget::clickSignSubmitBtn);
    connect(getVerifyCodeBtn, &QPushButton::clicked, this, &SelfInfoWidget::clickGetVerifyCodeBtn);
    connect(phoneSubmitBtn, &QPushButton::clicked, this, &SelfInfoWidget::clickPhoneSubmitBtn);
    connect(avatarBtn, &QPushButton::clicked, this, &SelfInfoWidget::clickAvatarBtn);
}

void SelfInfoWidget::clieckNameSubmitBtn()
{
    DataCenter* dataCenter = DataCenter::getInstance();

    // 1. 从输入框中，拿到修改后的昵称
    const QString& nickname = nameEdit->text();
    if (nickname.isEmpty() || nickname == dataCenter->getMyself()->nickname) {
        Toast::showMessage("无效的修改!");
        return ;
    }
    // 2. 发送网络请求
    connect(dataCenter, &DataCenter::changeNicknameDone, this, &SelfInfoWidget::clickNameSubmitBtnDone, Qt::UniqueConnection);
    dataCenter->changeNicknameAsync(nickname);
}

void SelfInfoWidget::clickNameSubmitBtnDone()
{
    // 把当前的 nameEdit 和 nameSubmitBtn 隐藏起来
    nameEdit->hide();
    nameSubmitBtn->hide();
    layout->removeWidget(nameEdit);
    layout->removeWidget(nameSubmitBtn);
    // 把 nameLabel 和 nameModifyBtn 显示出来
    nameLabel->show();
    nameModifyBtn->show();
    layout->addWidget(nameLabel, 1, 2);
    layout->addWidget(nameModifyBtn, 1, 3);
    // 把输入框的内容进行设置
    nameLabel->setText(nameEdit->text());
}

void SelfInfoWidget::clickSignSubmitBtn()
{
    DataCenter* dataCenter = DataCenter::getInstance();

    // 1. 从输入框中，拿到签名的内容
    const QString& sign = signEdit->text();
    if (sign.isEmpty() || sign == dataCenter->getMyself()->signature) {
        Toast::showMessage("无效的修改!");
        return ;
    }
    // 2. 发送网络请求
    connect(dataCenter, &DataCenter::changeSignatureDone, this, &SelfInfoWidget::clickSignatureBtnDone, Qt::UniqueConnection);
    dataCenter->changeSignatureAsync(sign);
}

void SelfInfoWidget::clickSignatureBtnDone()
{
    // 把当前的 signEdit 和 signSubmitBtn 隐藏起来
    signEdit->hide();
    signSubmitBtn->hide();
    layout->removeWidget(signEdit);
    layout->removeWidget(signSubmitBtn);
    // 把 signLabel 和 signModifyBtn 显示出来
    signLabel->show();
    signModifyBtn->show();
    layout->addWidget(signEdit, 2, 2);
    layout->addWidget(signSubmitBtn, 2, 3);
    // 把输入框的内容进行设置
    signLabel->setText(signEdit->text());
}

void SelfInfoWidget::clickGetVerifyCodeBtn()
{
    // 1. 先获取到输入框的手机号码
    const QString& phone = phoneEdit->text();
    if (phone.isEmpty()) {
        return ;
    }

    // 2. 给服务器发送请求
    DataCenter* dataCenter = DataCenter::getInstance();
    connect(dataCenter, &DataCenter::getVerifyCodeIdDone, this, [=]() {
        // 不需要做其他的处理，只需要提示一下，验证码已经发送
        Toast::showMessage("短信验证码已经发送");
    });
    dataCenter->getVerifyCodeAsync(phone);

    // 3. 把刚才发送请求的手机号码，保存起来
    this->phoneToChange = phone;

    // 4. 禁用发送验证码按钮，并给出倒计时
    this->getVerifyCodeBtn->setEnabled(false);

    QTimer* timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, [=]() {
        if (leftTime <= 1) {
            // 倒计时结束了
            getVerifyCodeBtn->setEnabled(true);
            getVerifyCodeBtn->setText("获取验证码");
            timer->stop();
            timer->deleteLater();
            leftTime = 30;
            return ;
        }
        --(leftTime);
        getVerifyCodeBtn->setText(QString::number(leftTime) + "s");
    });
    timer->start(1000);
}

void SelfInfoWidget::clickPhoneSubmitBtn()
{
    // 1. 先判定当前验证码是否已经收到
    DataCenter* dataCenter = DataCenter::getInstance();
    QString verifyCodeId = dataCenter->getVerifyCodeId();
    if (verifyCodeId.isEmpty()) {
        // 服务器这边还没有返回验证码响应
        Toast::showMessage("服务器尚未返回验证码!");
        return ;
    }
    dataCenter->resetVerifyCodeId("");

    // 2. 获取到用户输入的验证码
    QString verifyCode = verifyCodeEdit->text();
    if (verifyCode.isEmpty()) {
        Toast::showMessage("验证码不能为空");
        return ;
    }
    verifyCodeEdit->setText("");

    // 3. 发送请求，把当前验证码信息，发送给服务器
    connect(dataCenter, &DataCenter::changePhoneDone, this, &SelfInfoWidget::clickPhoneSubmitBtnDone, Qt::UniqueConnection);
    dataCenter->changePhoneAsync(this->phoneToChange, verifyCodeId, verifyCode);
}

void SelfInfoWidget::clickPhoneSubmitBtnDone()
{
    // 把 phoneEdit 和 phoneSubmitBtn 隐藏起来
    phoneEdit->hide();
    phoneSubmitBtn->hide();
    verifyCodeTag->hide();
    verifyCodeEdit->hide();
    getVerifyCodeBtn->hide();
    layout->removeWidget(phoneEdit);
    layout->removeWidget(phoneSubmitBtn);
    layout->removeWidget(verifyCodeTag);
    layout->removeWidget(verifyCodeEdit);
    layout->removeWidget(getVerifyCodeBtn);

    // 把当前的 phoneLabel 和 phoneModifyBtn 显示出来
    phoneLabel->show();
    phoneModifyBtn->show();
    layout->addWidget(phoneLabel, 3, 2);
    layout->addWidget(phoneModifyBtn, 3, 3);

    // 把输入框的内容进行设置
    phoneLabel->setText(this->phoneToChange);
}

void SelfInfoWidget::clickAvatarBtn()
{
    // 1. 弹出对话框, 选择文件
    QString filter = "Image Files (*.png *.jpg *.jpeg)";
    QString imagePath = QFileDialog::getOpenFileName(this, "选择头像", QDir::homePath(), filter);
    if (imagePath.isEmpty()) {
        // 用户取消了
        LOG() << "用户未选择任何头像";
        return ;
    }

    // 2. 根据路径读取到图片的内容
    QByteArray imageBytes = loadFileToByteArray(imagePath);

    // 3. 发送请求，修改头像
    DataCenter* dataCenter = DataCenter::getInstance();
    connect(dataCenter, &DataCenter::changeAvatarDone, this, &SelfInfoWidget::clickAvatarBtnDone, Qt::UniqueConnection);
    dataCenter->changeAvatarAsync(imageBytes);
}

void SelfInfoWidget::clickAvatarBtnDone()
{
    // 把设置的头像更新到界面上
    DataCenter* dataCenter = DataCenter::getInstance();
    avatarBtn->setIcon(dataCenter->getMyself()->avatar);
}
